#include <getopt.h>
#include <string.h>
#include <rtthread.h>
#include <aic_core.h>
#include <stdlib.h>
#include <sys/time.h>
#include "hal_adcim.h"
#include "rtdevice.h"
#include "aic_log.h"
#include "hal_gpai.h"
#include <stdio.h>
#include "aic_hal_gpio.h"


#include "Serial_Port_Analysis.h"//添加串口解析命令头文件

/////////////////添加串口解析命令函数

// 十六进制字符串转字节数组
uint8_t* hex_str_to_bytes(const char* hex_str, size_t* out_len) {
    char* tmp = strdup(hex_str);
    char* token = strtok(tmp, " ");
    uint8_t* bytes = malloc(strlen(hex_str)/3 + 1);
    size_t count = 0;

    while (token != NULL) {
        bytes[count++] = (uint8_t)strtol(token, NULL, 16);
        token = strtok(NULL, " ");
    }
    
    *out_len = count;
    free(tmp);
    return bytes;
}

// 数据包分割（改进版）
PacketList split_packets(const uint8_t* data, size_t len) {
    PacketList list = {NULL, 0};
    size_t start = 0;
    int in_packet = 0;

    for (size_t i = 0; i < len; ++i) {
        if (data[i] == HEADER && !in_packet) {
            start = i;
            in_packet = 1;
        } else if (data[i] == FOOTER && in_packet) {
            size_t pkt_len = i - start + 1;
            list.packets = realloc(list.packets, (list.count+1)*sizeof(Packet));
            list.packets[list.count].data = malloc(pkt_len);
            memcpy(list.packets[list.count].data, data+start, pkt_len);
            list.packets[list.count].length = pkt_len;
            list.count++;
            in_packet = 0;
        }
    }
    return list;
}



// 函数声明：计算校验和
// 参数：data - 指向数据数组的指针，length - 数据数组的长度
// 返回值：计算得到的校验和（8位无符号整数）
uint8_t calculate_checksum(uint8_t *data, size_t length) {
    uint32_t checksum = 0;  // 使用32位整数来避免溢出
    for (size_t i = 0; i < length - 2; i++) {
        checksum += data[i];
    }
    return checksum % 256;  // 取低8位
}


// 解析单个数据包（支持多命令）
ParsedPacket parse_packet(const uint8_t* data, size_t len) {
    ParsedPacket result = {0};
    // ADD_ParsedPacket ADD_result = {0};

    // 基础校验
    if (len < 5 || data[0] != HEADER || data[len-1] != FOOTER) {
        rt_kprintf("无效数据包\n");
        return result;
    }
    
    // 通用字段解析
    result.header = data[0];//包头
    result.length = data[1];//数据长度
    result.command = data[2];//命令
    result.footer = data[len-1];//包尾

    // 按命令类型处理
    switch (result.command) {
        case 0x20: { // 重量数据包
            if (len < 11) break;//15-4:data_len-4

            //校验码
            result.checksum = data[len-2];
            // 校验和校验
            uint8_t calculated_checksum = calculate_checksum(data, len-2);
            if (result.checksum != calculated_checksum) {
                rt_kprintf("校验和错误\n");
                return result;
            }

            // 符号和单位
            switch (data[3]) {
                case 0x81: strcpy(result.sign_unit, "+KG"); break;
                case 0x01: strcpy(result.sign_unit, "-KG"); break;
                default:   strcpy(result.sign_unit, "未知");
            }
            // 小数位
            result.decimal = data[4];

            // 净重（4字节大端）
            uint32_t net_weight_raw = (data[5] << 24) | (data[6] << 16) | (data[7] << 8) | data[8];
            result.net_weight = net_weight_raw / pow(10, result.decimal);

            // 稳定状态
            strcpy(result.stability, (data[9] == 0x0A) ? "稳定" : "不稳定");
            // 皮重（3字节）
            uint32_t tare = (data[10] << 16) | (data[11] << 8) | data[12];
            result.tare = tare / pow(10, result.decimal);
            break;
        }
        case 0x21: { // 取毛重或净重数据包
            if (len < 7) break;

            // 符号和单位
            switch (data[3]) {
                case 0x81: strcpy(result.sign_unit, "+KG"); break;
                case 0x01: strcpy(result.sign_unit, "-KG"); break;
                default:   strcpy(result.sign_unit, "未知");
            }
            // 小数位
            result.decimal = data[4];

            // 净重/毛重（4字节大端）
            uint32_t net_weight_raw = (data[5] << 24) | (data[6] << 16) | (data[7] << 8) | data[8];
            result.net_weight = net_weight_raw / pow(10, result.decimal);
            
            //校验码
            result.checksum = data[len-2];
            // 校验和校验
            uint8_t calculated_checksum = calculate_checksum(data, len-2);
            if (result.checksum != calculated_checksum) {
                rt_kprintf("校验和错误\n");
                return result;
            }
            break;
        }

        case 0x22: { // 去皮应答
            // 包头1 + 长度1 + 命令1 + 状态1 + 校验1 + 包尾1 = 6字节
            if (len != 6) {
                rt_kprintf("ERR: 去皮包长度错误\n");
                // return result;
            }
            // 状态字段解析
            switch (data[3]) {
                case 0x00: 
                    strncpy(result.ACK, "去皮成功", sizeof(result.ACK));
                                    // rt_kprintf("去皮成功\n");
                    break;
                case 0x01: 
                    strncpy(result.ACK, "拥堵去皮", sizeof(result.ACK));
                                    // rt_kprintf("拥堵，去皮失败\n");
                    break;
                case 0x02: 
                    strncpy(result.ACK, "非法命令", sizeof(result.ACK));
                                    // rt_kprintf("非法命令\n");
                    break;
                default:   
                    strncpy(result.ACK, "未知状态", sizeof(result.ACK));
                                    // rt_kprintf("未知状态\n");
            }
            break;
                   //校验码
            result.checksum = data[len-2];
            // 校验和校验
            uint8_t calculated_checksum = calculate_checksum(data, len-2);
            if (result.checksum != calculated_checksum) {
                rt_kprintf("校验和错误\n");
                return result;
            }
        }
        case 0x23: { // 回皮（取皮重）
            if (len < 7) break;

            // 符号和单位
            switch (data[3]) {
                case 0x81: strcpy(result.sign_unit, "+KG"); break;
                case 0x01: strcpy(result.sign_unit, "-KG"); break;
                default:   strcpy(result.sign_unit, "未知");
            }
            // 小数位
            result.decimal = data[4];

            // 皮重（4字节大端）
            uint32_t net_weight_raw = (data[5] << 24) | (data[6] << 16) | (data[7] << 8) | data[8];
            result.net_weight = net_weight_raw / pow(10, result.decimal);
            
            //校验码
            result.checksum = data[len-2];
            // 校验和校验
            uint8_t calculated_checksum = calculate_checksum(data, len-2);
            if (result.checksum != calculated_checksum) {
                rt_kprintf("校验和错误\n");
                return result;
            }
            break;
        }
        case 0x24: { // 置零应答
            if (len != 6) {
                rt_kprintf("ERR: 置零包长度错误\n");
                // return result;
            }
            // 状态字段解析
            switch (data[3]) {
                case 0x00: 
                    strncpy(result.ACK, "置零成功", sizeof(result.ACK));
                                    // rt_kprintf("去皮成功\n");
                    break;
                case 0x01: 
                    strncpy(result.ACK, "置零去皮", sizeof(result.ACK));
                                    // rt_kprintf("拥堵，去皮失败\n");
                    break;
                case 0x02: 
                    strncpy(result.ACK, "非法命令", sizeof(result.ACK));
                                    // rt_kprintf("非法命令\n");
                    break;
                default:   
                    strncpy(result.ACK, "未知状态", sizeof(result.ACK));
                                    // rt_kprintf("未知状态\n");
            }
            break;
                   //校验码
            result.checksum = data[len-2];
            // 校验和校验
            uint8_t calculated_checksum = calculate_checksum(data, len-2);
            if (result.checksum != calculated_checksum) {
                rt_kprintf("校验和错误\n");
                return result;
            }
        }



        
        default:
            rt_kprintf("未知命令: 0x%02X\n", result.command);
    }
    return result;
}



// 解析数据包,打印结果
void print_packet(const ParsedPacket* pkt) {
    char buffer[100];
    rt_kprintf("包头: 0x%02X\n", pkt->header);
    rt_kprintf("长度: 0x%02X\n", pkt->length);
    rt_kprintf("命令: 0x%02X\n", pkt->command);
    if (pkt->command == 0x20) {
        rt_kprintf("单位: %s\n", pkt->sign_unit);
        rt_kprintf("小数位: %d\n", pkt->decimal);

        snprintf(buffer, sizeof(buffer), "%.*f", pkt->decimal, pkt->net_weight);
        rt_kprintf("净重: %s\n", buffer);
        // rt_kprintf("净重: %.*f\n", pkt->decimal, pkt->net_weight);
        rt_kprintf("稳定状态: %s\n", pkt->stability);

        snprintf(buffer, sizeof(buffer), "%.*f", pkt->decimal, pkt->tare);
        rt_kprintf("皮重: %s\n", buffer);
        // rt_kprintf("皮重: %.*f\n", pkt->decimal, pkt->tare);
    } else if (pkt->command == 0x21) {
        rt_kprintf("单位: %s\n", pkt->sign_unit);
        rt_kprintf("小数位: %d\n", pkt->decimal);

        snprintf(buffer, sizeof(buffer), "%.*f", pkt->decimal, pkt->net_weight);
        rt_kprintf("净重/毛重: %s\n", buffer);
        // rt_kprintf("净重: %.*f\n", pkt->decimal, pkt->net_weight);
    }else if (pkt->command == 0x22) {
        rt_kprintf("去皮状态: %s\n", pkt->ACK);
    }else if (pkt->command == 0x23) {
        rt_kprintf("单位: %s\n", pkt->sign_unit);
        rt_kprintf("小数位: %d\n", pkt->decimal);

        snprintf(buffer, sizeof(buffer), "%.*f", pkt->decimal, pkt->net_weight);
        rt_kprintf("皮重: %s\n", buffer);
    }else if (pkt->command == 0x24) {
        rt_kprintf("置零状态: %s\n", pkt->ACK);
    }



    rt_kprintf("包尾: 0x%02X\n\n", pkt->footer);
}


/////////////////
